module IntraIRSlice where

import SliceSummary

import Data.IntSet ( IntSet )
import qualified Data.IntSet as IS

import LLVM.Analysis

------

sliceTransfer :: SliceInfo -> Instruction -> Analysis SliceInfo
sliceTransfer si i =   
  case i of
    BranchInst {branchCondition=cv,branchTrueTarget=tb,branchFalseTarget=fb} ->
      setTrCtrDep si i $! idsInBlks [tb,fb]
    SwitchInst {switchValue=sv, switchDefaultTarget=db, switchCases=cases} ->
      setTrCtrDep si i $! idsInBlks (db : map snd cases)
    IndirectBranchInst {indirectBranchAddress=ptr,indirectBranchTargets=bs} ->
      setTrCtrDep si i $! idsInBlks bs
--    UnconditionalBranchInst { unconditionalBranchTarget = bb } ->
--      setTrCtrDep si i $! idsInBlks [bb]
    
    StoreInst {storeAddress = ptr, storeValue = sv} -> 
      updSliInfo i (ptr,sv) si 
    AtomicRMWInst {atomicRMWPointer = ptr, atomicRMWValue = av} ->
      updSliInfo i (ptr,av) si
    AtomicCmpXchgInst {atomicCmpXchgPointer = ptr, atomicCmpXchgNewValue = nv} ->
      updSliInfo i (ptr,nv) si
      
    InsertValueInst {insertValueAggregate = a, insertValueValue = iv} -> 
      updSliInfo i (a,iv) si
----    PhiNode {} -> updSliInfo i (toValue i, toValue i) si
   
    RetInst {} ->  return si   
    _ -> setTrCtrDep si i IS.empty  
  where
    idsInBlks = IS.fromList . map instructionUniqueId . concatMap basicBlockInstructions
 
